package com.first.core.web.filter;

import java.io.IOException;
import java.util.HashMap;
import java.util.Set;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.security.AccessDeniedException;
import org.springframework.security.Authentication;
import org.springframework.security.GrantedAuthority;
import org.springframework.security.context.SecurityContextHolder;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import com.first.core.security.SecurityDataSource;


public class SecurityInterceptorFilter extends OncePerRequestFilter
{

    private HashMap roleUrlsMap;
    private SecurityDataSource securityDataSource;

    public SecurityInterceptorFilter()
    {
        roleUrlsMap = null;
    }

    public void setSecurityDataSource(SecurityDataSource securityDataSource)
    {
        this.securityDataSource = securityDataSource;
    }

    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain)
        throws ServletException, IOException
    {
        String url = request.getRequestURI();
        if(StringUtils.hasLength(request.getContextPath()))
        {
            String contextPath = request.getContextPath();
            int index = url.indexOf(contextPath);
            if(index != -1)
            {
                url = url.substring(index + contextPath.length());
            }
        }
        Authentication auth = SecurityContextHolder.getContext().getAuthentication();
        boolean isSuperUser = false;
        for(int i = 0; i < auth.getAuthorities().length; i++)
        {
            if(!"超级管理员".equals(auth.getAuthorities()[i].getAuthority()))
            {
                continue;
            }
            isSuperUser = true;
            break;
        }

        if(!isSuperUser && !isUrlGrantedRight(url, auth))
        {
            if(logger.isDebugEnabled())
            {
                logger.info((new StringBuilder("ungranted url:")).append(url).toString());
            }
            if(url.startsWith("/mobile/"))
            {
                response.sendRedirect((new StringBuilder(String.valueOf(request.getContextPath()))).append("/mobile/login.jsp").toString());
                return;
            } else
            {
                throw new AccessDeniedException((new StringBuilder("Access is denied! Url:")).append(url).append(" User:").append(SecurityContextHolder.getContext().getAuthentication().getName()).toString());
            }
        }
        if(logger.isDebugEnabled())
        {
            logger.debug((new StringBuilder("pass the url:")).append(url).toString());
        }
        chain.doFilter(request, response);
    }

    private boolean isUrlGrantedRight(String url, Authentication auth)
    {
        GrantedAuthority agrantedauthority[];
        int j = (agrantedauthority = auth.getAuthorities()).length;
        for(int i = 0; i < j; i++)
        {
            GrantedAuthority ga = agrantedauthority[i];
            String authority=ga.getAuthority();
            Set urlSet = (Set)roleUrlsMap.get(authority);
            if(urlSet != null && urlSet.contains(url))
            {
                return true;
            }
        }

        return false;
    }

    public void loadDataSource()
    {
        roleUrlsMap = securityDataSource.getDataSource();
    }

    public void afterPropertiesSet()
        throws ServletException
    {
        loadDataSource();
        if(roleUrlsMap == null)
        {
            throw new RuntimeException("没有进行设置系统的权限匹配数据源");
        } else
        {
            return;
        }
    }
}
